package cn.iocoder.boot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.iocoder.boot.controller.admin.vo.ReplaceRelationManagementVO;
import cn.iocoder.boot.dto.ComponentPageDTO;
import cn.iocoder.boot.dto.ReplaceRelationManagementDTO;
import cn.iocoder.boot.entity.ReplaceRelationManagement;
import cn.iocoder.boot.entity.gc.ComponentData;
import cn.iocoder.boot.entity.gc.ComponentDataHeaderField;
import cn.iocoder.boot.mapper.ComponentDao;
import cn.iocoder.boot.mapper.ComponentDataHeaderFieldDao;
import cn.iocoder.boot.mapper.ReplaceRelationMapper;
import cn.iocoder.boot.service.ReplaceRelationService;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.serviceException;

@Service
public class ReplaceRelationServiceImpl extends ServiceImpl<ReplaceRelationMapper, ReplaceRelationManagement> implements ReplaceRelationService {


    @Resource
    private ComponentDao componentDao;
    @Resource
    private ComponentDataHeaderFieldDao componentDataHeaderFieldDao;
    @Resource
    private ReplaceRelationMapper replaceRelationManagementMapper;

    @Override
    public Page<ReplaceRelationManagement> getReplaceRelationManagementPage(ReplaceRelationManagementDTO dto) {
        Page<ReplaceRelationManagement> page = new Page<>(dto.getPageNo(), dto.getPageSize());
        // 这里可以根据需要设置分页参数
        LambdaUpdateWrapper<ReplaceRelationManagement> wrapper = Wrappers.lambdaUpdate();
        wrapper.like(Objects.nonNull(dto.getModel()), ReplaceRelationManagement::getModel, dto.getModel());
        wrapper.eq(Objects.nonNull(dto.getType()), ReplaceRelationManagement::getType, dto.getType());
        wrapper.eq(Objects.nonNull(dto.getBrand()), ReplaceRelationManagement::getBrand, dto.getBrand());
        wrapper.like(Objects.nonNull(dto.getSpecifications()), ReplaceRelationManagement::getSpecifications, dto.getSpecifications());

        wrapper.eq(ReplaceRelationManagement::getParentId, 0);
        Page<ReplaceRelationManagement> parentList = replaceRelationManagementMapper.selectPage(page, wrapper);
        List<ReplaceRelationManagement> records = parentList.getRecords();
        if (CollectionUtils.isNotEmpty(records)) {
            //查询子节点数据
            List<Long> ids = records.stream()
                    .map(ReplaceRelationManagement::getId)
                    .toList();
            List<ReplaceRelationManagement> list = replaceRelationManagementMapper.selectList(Wrappers.lambdaQuery(ReplaceRelationManagement.class).in(ReplaceRelationManagement::getParentId, ids));
            // 创建一个映射，将父节点ID映射到其子节点列表
            Map<Long, List<ReplaceRelationManagement>> childMap = list.stream()
                    .collect(Collectors.groupingBy(ReplaceRelationManagement::getParentId));

            // 将子节点归类到对应的父节点中
            for (ReplaceRelationManagement record : records) {
                List<ReplaceRelationManagement> children = childMap.get(record.getId());
                if (CollectionUtils.isNotEmpty(children)) {
                    record.setChildren(children);
                }
            }
            return parentList;
        }
        return new Page<>();
    }

    @Override
    public ReplaceRelationManagementVO getReplaceRelationManagement(Long id) {
        ReplaceRelationManagement entity = replaceRelationManagementMapper.selectById(id);
        return convertToVO(entity);
    }

    @Override
    @DSTransactional
    public boolean createReplaceRelationManagement(ReplaceRelationManagementDTO dto) {
        // 检验当前主元器件型号是否已存在替代关系  有 返回提示
        if (Objects.isNull(dto.getId())) {
            ReplaceRelationManagement replaceRelationManagement = replaceRelationManagementMapper.selectOne(Wrappers.lambdaQuery(ReplaceRelationManagement.class)
                    .eq(ReplaceRelationManagement::getModel, dto.getModel())
                    .eq(ReplaceRelationManagement::getParentId, 0).last("limit 1"));
            if (Objects.nonNull(replaceRelationManagement)) {
                throw serviceException(String.format("此型号：%s已经有替代料关系，请勿重复添加", replaceRelationManagement.getModel()));
            }
        }
        ReplaceRelationManagement entity = new ReplaceRelationManagement();
        BeanUtils.copyProperties(dto, entity);
        List<ReplaceRelationManagement> children = dto.getChildren();
        this.saveOrUpdate(entity);
        if (CollectionUtils.isNotEmpty(children)) {
            List<ReplaceRelationManagement> list = BeanUtil.copyToList(children, ReplaceRelationManagement.class);
//            // 过滤出需要新增的记录
            List<ReplaceRelationManagement> toInsertList = list.stream()
//                    .filter(item -> item.getId() == null || !existingIds.contains(item.getId()))
                    .filter(item -> item.getId() == null)
                    .toList();
            if (CollectionUtils.isEmpty(toInsertList)) {
                //校验是否是删除数据 先查询原有子数据 再和传入数据对比 得出需要删除的子数据
                List<ReplaceRelationManagement> existingList = replaceRelationManagementMapper.selectList(
                        Wrappers.lambdaQuery(ReplaceRelationManagement.class)
                                .eq(ReplaceRelationManagement::getParentId, entity.getId()));

                Set<Long> incomingIds = list.stream()
                        .map(ReplaceRelationManagement::getId)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toSet());

                List<ReplaceRelationManagement> toDeleteList = existingList.stream()
                        .filter(e -> !incomingIds.contains(e.getId()))
                        .toList();
                if (CollectionUtils.isNotEmpty(toDeleteList)) {
                    Set<Long> collect = toDeleteList.stream().map(ReplaceRelationManagement::getId).collect(Collectors.toSet());
                    replaceRelationManagementMapper.deleteBatchIds(collect);
                }
                return true;
            }
            toInsertList.forEach(e -> {
                e.setParentId(entity.getId());
                e.setId(null);
            });
            return this.saveBatch(toInsertList);
        }
        return true;
    }

    @Override
    public void updateReplaceRelationManagement(ReplaceRelationManagementDTO dto) {
        ReplaceRelationManagement entity = new ReplaceRelationManagement();
        BeanUtils.copyProperties(dto, entity);
        replaceRelationManagementMapper.updateById(entity);
    }

    @Override
    public boolean deleteReplaceRelationManagement(Long id) {
        return replaceRelationManagementMapper.deleteById(id) > 0;
    }

    @Override
    @DS("gc")
    public Map getPageInfo(ComponentPageDTO componentPageDTO) {
        List<Map<String, Object>> updatedMap = new ArrayList<>();
        LambdaQueryWrapper<ComponentData> queryWrapper = Wrappers.lambdaQuery();
        if (componentPageDTO.getModel() != null) {
            queryWrapper.like(ComponentData::getPartNumber, componentPageDTO.getModel());
        }
        Page<ComponentData> page = new Page<>(componentPageDTO.getPageNo(), componentPageDTO.getPageSize());
        Page<ComponentData> componentDataPage = componentDao.selectPage(page, queryWrapper);

        List<ComponentData> componentDataList = componentDataPage.getRecords();
        LambdaQueryWrapper<ComponentDataHeaderField> wrapper = Wrappers.lambdaQuery();
        //查询key值字段名
        List<Long> list = componentDataList.stream()
                .map(ComponentData::getSetId)
                .distinct()
                .collect(Collectors.toList());
        wrapper.in(ComponentDataHeaderField::getSetId, list);
        List<ComponentDataHeaderField> fieldList = componentDataHeaderFieldDao.selectList(wrapper);
        //分组
        Map<Long, List<ComponentDataHeaderField>> longListMap = fieldList.stream()
                .collect(Collectors.groupingBy(ComponentDataHeaderField::getSetId));
        for (ComponentData componentData : componentDataList) {
            List<ComponentDataHeaderField> headerFieldList = longListMap.get(componentData.getSetId());
            String jsonString = componentData.getTechTemplateFields();

            // 转换为 Map
            Map<String, String> fieldMapping = headerFieldList.stream()
                    .collect(Collectors.toMap(ComponentDataHeaderField::getFieldKey, ComponentDataHeaderField::getFieldName));
            // 解析JSON字符串为Map
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, String> fieldsMap = null;
            try {
                fieldsMap = objectMapper.readValue(jsonString, new TypeReference<Map<String, String>>() {
                });
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
            // 替换键名
            Map<String, Object> hashMap = new HashMap<>();
            Map<String, Object> pageMap = new HashMap<>();
            for (Map.Entry<String, String> entry : fieldsMap.entrySet()) {
                String newKey = fieldMapping.getOrDefault(entry.getKey(), entry.getKey());
                addData(hashMap, newKey, entry.getValue());
            }
            pageMap.put("brand", hashMap.get("厂商"));
            pageMap.put("model", hashMap.get("产品型号"));
            pageMap.put("specifications", hashMap.get("描述"));
            pageMap.put("encapsulation", hashMap.get("封装类型"));
            pageMap.put("dataSource", componentData.getDataSource());
            if (Objects.nonNull(componentData.getComponentImages())) {
                //拼接url
                String url = "http://192.168.10.185/to/api/base/file/content/get/" + componentData.getComponentImages();
                pageMap.put("picUrl", url);
            }
            updatedMap.add(pageMap);
        }
        HashMap<Object, Object> newHashMap = MapUtil.newHashMap();
        newHashMap.put("total", page.getTotal());
        newHashMap.put("pages", page.getPages());
        newHashMap.put("size", page.getSize());
        newHashMap.put("current", page.getCurrent());
        newHashMap.put("records", updatedMap);
        return newHashMap;
    }

    private static void addData(Map<String, Object> hashMap, String newKey, Object value) {
        // 如果 Map 中已经包含该键
        if (hashMap.containsKey(newKey)) {
            // 获取对应的值，并添加值
            String str = (String) hashMap.get(newKey);
            String s = str + value.toString();
            hashMap.put(newKey, s);
        } else {
            // 否则创建一个新的集合，添加值，并放入 Map
            hashMap.put(newKey, value);
        }
    }

    private ReplaceRelationManagementVO convertToVO(ReplaceRelationManagement entity) {
        ReplaceRelationManagementVO vo = new ReplaceRelationManagementVO();
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }
}
